package com.miyake.client.datamanage;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.miyake.client.DataService;
import com.miyake.client.DataServiceAsync;
import com.miyake.client.datamanage.plugin.PluginProperty;
import com.miyake.client.datamanage.plugin.MyAnalysisPluginChooser;
import com.miyake.client.datamanage.plugin.ReAnalyzeDialog;
import com.miyake.client.tools.ClickableLabel;
import com.miyake.client.tools.ShowDialog;
import com.miyake.client.tools.SmallButton;
import com.miyake.client.tools.WaitPopup;

public class DataPage extends Page {
	private DataServiceAsync service = DataService.Util.getInstance();
	private List<CheckBox> checkList = new ArrayList<CheckBox>();
	protected int column;
	private String fileUrl;
	protected String analysisURL;
	private int columnCount;
	protected String csvUrl;
	
	public DataPage(NodeProperty node, VerticalPanel panel) {
		super(node, panel);
	}
	
	@Override
	protected Widget getContent(NodeProperty node, DataServiceAsync service) {
		VerticalPanel panel = new VerticalPanel();
		panel.setWidth("100%");
		if (canEdit()) {
			panel.add(createToolBar());
		}
		showData(node, panel, service);

		return panel;
	}

	private HorizontalPanel createToolBar() {
		HorizontalPanel toolBar = new HorizontalPanel();
//		toolBar.setWidth("100%");
		toolBar.add(new SmallButton("Add Chart", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (createHandler != null) {
					createHandler.onNewPlot(columnCount);
				}
			}
		}));
		toolBar.add(new SmallButton("Add Table", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (createHandler != null) {
					createHandler.onNewTable();
				}
			}
		}));
		toolBar.add(new SmallButton("CSV", new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Window.open(csvUrl, "", "menubar=no,location=no,resizable=no,scrollbars=yes,status=no,toolbar=no,width=0,height=0,visible=no");
			}
			
		}));
		
		toolBar.add(new SmallButton("Add Text", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (createHandler != null) {
					createHandler.onNewText();
				}
			}
		}));
		
		toolBar.add(new SmallButton("Analyze", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				new DoAnalysis(getNode().getKey(), columnCount, updateHandler);
			}
		}));

		return toolBar;
	}
	
	private void showData(final NodeProperty node, final VerticalPanel panel, final DataServiceAsync service) {
		final Grid grid = new Grid();
		grid.setBorderWidth(1);
		grid.setVisible(false);
		final CheckBox check = new CheckBox("Show first 5 rows of the stored data");
		check.setValue(false);
		check.setVisible(false);
		check.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				grid.setVisible(check.getValue());
			}
		});
		grid.setVisible(check.getValue());
		final Grid dataProp = new Grid();
		dataProp.resize(1, 3);
		panel.add(dataProp);
		panel.add(check);
		panel.add(grid);
		
		
		final Grid paramGrid = new Grid();
		panel.add(paramGrid);
		service.getData(node.getKey(), new AsyncCallback<Data>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());
			}

			@Override
			public void onSuccess(Data result) {
				if (result.isParsed()) {
					check.setVisible(true);
				}
				fileUrl = result.getFileURL();
				analysisURL = result.getAnalysisURL();
				columnCount = result.getTextData().size();
				csvUrl = GWT.getHostPageBaseURL() + "fileServlet/" + getNode().getName()+ ".csv?type=csv&key=" + result.getKey();
				
				showDataProperty(dataProp, result);
				showSummaryGrid(node, grid, result);
				showParameter(paramGrid, result);
			}

		});
		
		//new ShowChildList(node, panel, updateHandler);
		ShowSubItems showSub = new ShowSubItems(node, panel, updateHandler);
		//showSub.setRecursible(false);
		showSub.update();
	}

	protected void showParameter(Grid grid, Data result) {
		grid.resize(result.getParameters().size() + 1, 3);
		int row = 1;
		grid.setWidget(0, 0, new HTML("<b>Parameters</b>"));
		for (Parameter p : result.getParameters()) {
			grid.setText(row, 0, p.getTitle() + ":");
			grid.setText(row, 1, p.getValue());
			grid.setText(row, 2, p.getUnit());
			row++;
		}
	}

	private CheckBox createCheckBox(int row, final NodeProperty node) {
		CheckBox check = new CheckBox();
		checkList.add(check);
		check.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
			@Override
			public void onValueChange(
					ValueChangeEvent<Boolean> event) {
				setTitleRow(checkList.size(), event.getValue(), node);
			}
		});
		return check;
	}

	protected void setTitleRow(int num, Boolean value, NodeProperty node) {
		int i = 0;
		for (CheckBox check : checkList) {
			if (check.getValue().equals(true)) {
				i++;
			}
			else {
				break;
			}
		}
		
		Data data = new Data();
		data.setTitleRow(i);

		service.updateData(node.getKey(), data, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(Void result) {
			}
			
		});
	}
	
	private void showDataProperty(final Grid dataProp, Data result) {
		dataProp.setWidget(0, 0, new HTML("<b>Data Properties</b>"));
//		dataProp.setWidget(0, 1, new HTML("<a href=\"" + GWT.getHostPageBaseURL() + "fileServlet/" + getNode().getName()+ ".csv?type=csv&key=" + result.getKey() + "\">csv</a>"));

		if (result.getSourceType().equals(Data.SourceTypeFile)) {
			showFileProperty(dataProp, result);
		}
		else if (result.getSourceType().equals(Data.SourceTypeAnalysis)){
			showAnalysisPlugin(dataProp, result);
		}
	}

	protected void showAnalysisPlugin(final Grid dataProp, final Data result) {
		dataProp.resize(3, 3);
		dataProp.setText(1, 0, "Source Type:");
		dataProp.setText(1, 1, "Analysis");
		dataProp.setWidget(1, 2, new SmallButton("Re-Analyze", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				reanalyze(result.getAnalysisPluginKey());
			}
		}));
		dataProp.setText(2, 0, "Processing Engine:");
		final Label label = new Label();
		dataProp.setWidget(2, 1, label);
		service.getPlugin(result.getAnalysisPluginKey(), new AsyncCallback<PluginProperty>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());
			}

			@Override
			public void onSuccess(PluginProperty result) {
				label.setText(result.getName());
			}
		
		});
	}

	protected void reanalyze(final String pluginKey) {
		final ReAnalyzeDialog dlg = new ReAnalyzeDialog() {
			@Override
			protected String getPluginKey() {
				return pluginKey;
			}

			@Override
			protected String getNodeKey() {
				return getNode().getKey();
			}
		};
		
		new ShowDialog() {
			@Override
			protected void onOK(String text) {
				WaitPopup.showPopup();
				service.doReAnalysis(getNode().getKey(), pluginKey, dlg.getAnalysisSetup(), new AsyncCallback<String>() {
					@Override
					public void onFailure(Throwable caught) {

					}

					@Override
					public void onSuccess(String result) {
						WaitPopup.hidePopup();
						fireNodeUpdateEvent(getNode().getKey());
					}
					
				});
			}

			@Override
			protected DialogBox getDialogBox() {
				return dlg;
			}
		};
	}

	protected void showFileProperty(final Grid dataProp, Data result) {
		dataProp.resize(4, 2);
		dataProp.setText(1, 0, "Source Type:");
		dataProp.setText(1, 1, "File");
		dataProp.setText(2, 0, "File Name:");
		dataProp.setWidget(2, 1, new ClickableLabel(result.getFilename(), new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				Window.open(fileUrl, "", "menubar=no,location=no,resizable=no,scrollbars=yes,status=no,toolbar=no,width=0,height=0,visible=no");
			}
		}));
		dataProp.setText(3, 0, "File Parser:");
		if (result.isParsed()) {
			HorizontalPanel p = new HorizontalPanel();
			//p.add(new HTML("<a href=\"\">" + "OpenOtdr" + "</a>"));
			final Label label = new Label();
			p.add(label);
			if (result.getFilePluginKey() != null) {
				getPluginName(result, label);
				p.add(new SmallButton("Change", new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						showFilePluginDialog();
					}
				}));
				
			}
			else {
				p.add(new Label("Parsed"));
			}
			dataProp.setWidget(3, 1, p);
		}
		else {
			HorizontalPanel p = new HorizontalPanel();
			p.add(new Label("Not Parsed"));
			p.add(new SmallButton("Select", new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					showFilePluginDialog();
				}
			}));
			dataProp.setWidget(3, 1, p);
		}
	}

	protected void reparse() {
		WaitPopup.showPopup();
		service.doParse(getNode().getKey(), new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());
			}

			@Override
			public void onSuccess(Void result) {
				WaitPopup.hidePopup();
				fireNodeUpdateEvent("");
			}
			
		});
	}

	protected void getPluginName(Data result, final Label label) {
		service.getPlugin(result.getFilePluginKey(), new AsyncCallback<PluginProperty>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(PluginProperty result) {
				label.setText(result.getName());
			}
		});
	}

	private VerticalPanel createTitle(Data result) {
		VerticalPanel p = new VerticalPanel();
		p.setWidth("100%");
		Label c = new Label("C"+(column+1));
		c.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		p.add(c);
		Label tltLable = new Label(result.getTitles().get(column));
		p.add(tltLable);
		tltLable.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		return p;
	}
	
	private void showSummaryGrid(final NodeProperty node, final Grid grid,
			Data result) {
		List<String[]> data = result.getTextData();
		grid.resize(data.get(0).length + 1, data.size() + 1);
		column = 0;
		grid.setText(0, 0, "Title Row");
		for (String[] s : data) {
			grid.setWidget(0, column+1, createTitle(result));
			for (int row = 0; row < s.length; row++) {
				if (column == 0) {
					CheckBox check = createCheckBox(row, node);
					grid.setWidget(row + 1, 0, check);
					if (row < result.getTitleRow()) {
						check.setValue(true);
					}
				}
				grid.setText(row + 1, column + 1, s[row]);
			}
			column++;
		}
	}

	private void showFilePluginDialog() {
		new ParseFile(getNode().getKey()) {
			
			@Override
			protected void onParseFinish(String nodeKey) {
				fireNodeUpdateEvent(getNode().getKey());
			}
		};
	}


}
